/**
 * ak yy-ds @2021
 */
package com.cxps.cloud.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.MessageDigest;

/**
 * MD5加密工具类
 *
 * @author YC.Liu 学无止境
 * @since 2021/8/5
 * ...
 */
public class MD5Util {

    /**
     * MD5算法是一种非常优秀的加密算法。一般用于密码加密、确保信息的传输等工作
     * <p>
     * 特点：
     *      1、灵活性
     *      2、不可逆
     *      3、防篡改
     *      4、
     */

    public static void main(String[] args) {
        String strMD5 = getStrMD5("123456");
        System.out.println(strMD5);

        String strMD51 = getStrMD5("abc");
        System.out.println(strMD51);

    }

    /**
     * 字符串加密
     *
     * @param str
     * @return
     */
    public static String getStrMD5(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            return new String(encode(digest.digest(str.getBytes())));
        } catch (Exception e) {
            throw new RuntimeException("md5 digest fail:", e);
        }
    }

    /**
     * 文件加密
     *
     * @param file
     * @return
     */
    public static String getFileMD5(File file) {
        FileInputStream in = null;
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            if (!file.isFile()) {
                throw new RuntimeException("md5 digest fail: file not exists!");
            }
            byte buffer[] = new byte[1024];
            int len;
            in = new FileInputStream(file);
            while ((len = in.read(buffer, 0, 1024)) != -1) {
                digest.update(buffer, 0, len);
            }
            return new String(encode(digest.digest()));
        } catch (Exception e) {
            throw new RuntimeException("md5 digest fail:", e);
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static final char[] HEX = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    private static char[] encode(byte[] bytes) {
        final int nBytes = bytes.length;
        char[] result = new char[2 * nBytes];
        int j = 0;
        for (int i = 0; i < nBytes; i++) {
            // Char for top 4 bits
            result[j++] = HEX[(0xF0 & bytes[i]) >>> 4];
            // Bottom 4
            result[j++] = HEX[(0x0F & bytes[i])];
        }
        return result;
    }

}
